#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h> //包含套接字的函数库 
#include <netinet/in.h> //包含AF_INET的相关结构 
#include <arpa/inet.h> //包含AF_INET的操作函数 
#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h>
#include <dirent.h>
#include <pthread.h>

#define PORT 666
#define KEY_LEN 52
#define VALUE_LEN 100
#define BUF_LEN 156
struct msg
{
	int data_len;
	char name[KEY_LEN];
	char data[VALUE_LEN];
};
void* thread( void *arg );
int main(int argc ,char* args[]){

int s_fd,c_fd;//服务器，客服端套　接字标识符
int s_len,c_len;//服务器，客户端　消息长度
struct sockaddr_in s_addr;//服务器套接字地址
struct sockaddr_in c_addr;//客户端套接字地址
int dataBytes = 0;//读取消息长度

//消息
char sendbuf[BUF_LEN];
char recvbuf[BUF_LEN];

/*
socket函数，失败返回-1 
 int socket(int domain, int type, int protocol); 
 第一个参数表示使用的地址类型，一般都是ipv4即AF_INET 
 第二个参数表示套接字类型：tcp一般用SOCK_STREAM数据流传输 
 第三个参数设置为0 
创建套接字
*/
s_fd = socket(AF_INET,SOCK_STREAM,0);

if(s_fd < 0){
	perror("创建套接字失败！");
	return -1;
}
printf("开启套接字成功！\n");

/*
开启地址复用
*/
int optval = 1;//１允许地址复用，０禁止
int optlen = sizeof(optval);
setsockopt(s_fd,SOL_SOCKET,SO_REUSEADDR,&optval,optlen);

/*
初始化服务器套接字
*/
//定义地址域，AF_INET指ipv4
s_addr.sin_family = AF_INET;
//定义端口
s_addr.sin_port = htons(PORT);
//定义地址,INADDR_ANY 代表0.0.0.0　指所有地址
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);

/*
绑定端口，ｉｐ
*/
s_len = sizeof(s_addr);
if(bind(s_fd,(struct sockaddr*)&s_addr,s_len) < 0){

	perror("绑定失败！");
	return -1;
}

/*
设置监听
*/
if(listen(s_fd,10) < 0){
	perror("监听失败！");
	return -1;
}
FILE *fp = NULL;
while(1)
	{
		c_len = sizeof(c_addr);

	    c_fd = accept(s_fd,(struct sockaddr*)&c_addr,(socklen_t*)&c_len);

		if(c_fd < 0){
			perror("accept 失败!");
			return -1;
		}

		printf("%s\n", inet_ntoa(c_addr.sin_addr));
		printf("%d\n", htons(c_addr.sin_port));
		printf("等待消息\n");

	
		//dataBytes = 0;
		//fflush(stdout);
		 pthread_t th;
	    int ret;
	    //int *thread_ret = NULL;
	    ret = pthread_create( &th, NULL, thread, &c_fd );
	    if( ret != 0 ){
	        printf( "Create thread error!\n");
	        return -1;
	    }
	    //pthread_detach(th);
	    /*printf( "This is the main process.\n" );
	    pthread_join( th, (void**)&thread_ret );
	    printf( "thread_ret = %d.\n", *thread_ret );*/
		
 }
	
return 0;
}
void* thread( void *arg )
{
	pthread_detach(pthread_self());
	int c_fd = *(int *)arg;
	char recvbuf[BUF_LEN];
	char sendbuf[BUF_LEN];
    memset(recvbuf,0,sizeof(recvbuf));

	     while(recv(c_fd,recvbuf,2,0) > 0){

	     	char para[50];
	     	memset(para,0,sizeof(para));
	     	strncpy(para,recvbuf,sizeof(recvbuf));
	     	if(strncmp(para,"ls",2)==0){
					DIR *dirp; 
				    struct dirent *dp;
				    dirp = opendir("./"); //打开目录指针
				    while ((dp = readdir(dirp)) != NULL) { //通过目录指针读目录
				        //printf("%s\n", dp->d_name );
				        memset(sendbuf,0,sizeof(sendbuf));
				        struct msg ss;
				        memset(&ss,0,sizeof(struct msg));
				    
				        ss.data_len=strlen(dp->d_name);
				        memcpy(&ss.data,dp->d_name,strlen(dp->d_name));
				        memcpy(sendbuf,&ss,sizeof(struct msg));
				        int j=0;
				        for(j=0;j<156;j++){
							printf("%c", ss.data[j]);
						}
				        printf("\n");
				        send(c_fd,sendbuf,sizeof(struct msg),0);
				    }      
				    (void) closedir(dirp); //关闭目录
				    memset(sendbuf,0,sizeof(sendbuf));
				    strncpy(sendbuf,"finish",6);
				    send(c_fd,sendbuf,sizeof(struct msg),0);
				    printf("完成\n");
			}
	    }
    
}